<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Shop\Controller;

use Admin\Data\Common;
use Admin\Service\Common\ShopMessage;
use Doctrine\ORM\EntityManager;
use Laminas\Math\Rand;
use Laminas\Mvc\Controller\AbstractActionController;
use Laminas\Mvc\I18n\Translator;
use Laminas\View\Model\ViewModel;
use Shop\Form\ForgetPasswordForm;
use Shop\Form\OtherUserLoginForm;
use Shop\Form\OtherUserRegisterForm;
use Shop\Form\PhoneForgetPasswordForm;
use Shop\Form\ResetUserPasswordForm;
use Shop\Form\UserLoginForm;
use Shop\Form\UserPhoneLoginForm;
use Shop\Form\UserPhoneRegisterForm;
use Shop\Form\UserRegisterForm;
use Shop\Service\ShopUserManager;
use User\Entity\User;
use User\Entity\UserOtherLogin;
use User\Service\Common\UserAppLogin;
use User\Service\UserOtherLoginManager;

class UserController extends AbstractActionController
{
    private $translator;
    private $entityManager;
    private $shopUserManager;
    private $userOtherLoginManager;

    public function __construct(
        Translator      $translator,
        EntityManager   $entityManager,
        ShopUserManager $shopUserManager,
        UserOtherLoginManager $userOtherLoginManager
    )
    {
        $this->translator   = $translator;
        $this->entityManager= $entityManager;
        $this->shopUserManager = $shopUserManager;
        $this->userOtherLoginManager = $userOtherLoginManager;
    }

    /**
     * 会员登录
     * @return \Laminas\Http\Response|\Laminas\View\Model\ViewModel|UserLoginForm[]
     */
    public function indexAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        //判断是否有跳转去站外登录
        if (Common::configValue('user_login_url', 'customer')) return $this->redirect()->toUrl(urldecode(Common::configValue('user_login_url', 'customer')));

        $this->layout()->setVariable('titleName', $this->translator->translate('会员登录'));

        $form = new UserLoginForm($this->entityManager);

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();

            //登录前的处理，常见于整合第三方系统会员
            $response = $this->getEventManager()->trigger('shop.user.login.pre', $this, ['postData' => $data]);
            if($response->stopped()) {
                return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', [], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user');
            }

            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $loginStatus = $this->shopUserManager->userLogin($data);
                if(is_numeric($loginStatus) && $loginStatus == -1) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('登录信息错误!'));
                    return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', [], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user');
                }

                $this->getEventManager()->trigger('shop.user.login.post', $this, ['user' => $loginStatus]);

                return !empty($data['httpReferer']) ? $this->redirect()->toUrl(urldecode($data['httpReferer'])) : $this->redirect()->toRoute('shop');
            }
        }

        $httpReferer = $this->params()->fromQuery('httpReferer', '');
        if(!empty($httpReferer)) $form->get('httpReferer')->setValue($httpReferer);

        //第三方登录项
        $enableLogin = $this->shopPlugin()->enableOtherLogin();

        $userLoginPartial = $this->shopPlugin()->shopPartial('userLogin');

        return ['form' => $form, 'enableLogin' => $enableLogin, 'userLoginPartial' => $userLoginPartial];
    }

    /**
     * 手机号码登录
     * @return array|\Laminas\Http\Response|mixed
     */
    public function phoneLoginAction()
    {
        if (!Common::configValue('quick_login', 'customer')) return $this->response->setContent('Quick Login Close');

        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('会员登录'));

        $phoneArea  = Common::getPhoneArea();
        $form       = new UserPhoneLoginForm($phoneArea);
        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();

            //登录前的处理，常见于整合第三方系统会员
            $response = $this->getEventManager()->trigger('shop.user.phone-login.pre', $this, ['postData' => $data]);
            if($response->stopped()) {
                return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', [], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user');
            }
            $lastArray = $response->last();

            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $loginStatus = $this->shopUserManager->userPhoneLogin($data);
                if(is_numeric($loginStatus) && $loginStatus == -1) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('登录信息错误!'));
                    return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', ['action' => 'phoneLogin'], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user', ['action' => 'phoneLogin']);
                }

                $this->shopPlugin()->unsetPhoneCaptchaData();

                if (isset($lastArray['phoneAddUser']) && $lastArray['phoneAddUser']) {//已经新增客户
                    $this->getEventManager()->trigger('shop.user.register.post', $this, ['user' => $loginStatus]);
                    if($loginStatus->getUserStatus() == 3) return $this->redirect()->toRoute('shop-user');
                }

                $this->getEventManager()->trigger('shop.user.login.post', $this, ['user' => $loginStatus]);

                return !empty($data['httpReferer']) ? $this->redirect()->toUrl(urldecode($data['httpReferer'])) : $this->redirect()->toRoute('shop');
            }
        }

        $httpReferer = $this->params()->fromQuery('httpReferer', '');
        if(!empty($httpReferer)) $form->get('httpReferer')->setValue($httpReferer);

        //第三方登录项
        $enableLogin = $this->shopPlugin()->enableOtherLogin();

        $userLoginPartial = $this->shopPlugin()->shopPartial('userLogin');

        return ['form' => $form, 'phoneArea' => $phoneArea, 'enableLogin' => $enableLogin, 'userLoginPartial' => $userLoginPartial];
    }

    /**
     * 会员注册
     * @return bool[]|\Laminas\Http\Response|UserRegisterForm[]
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function userRegisterAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        //判断是否有跳转去站外注册
        if (Common::configValue('user_register_url', 'customer')) return $this->redirect()->toUrl(urldecode(Common::configValue('user_register_url', 'customer')));

        $this->layout()->setVariable('titleName', $this->translator->translate('会员注册'));

        //判断会员注册是否关闭
        if(Common::configValue('register_status', 'customer') != 1) return ['registerStatus' => false, 'registerCloseMessage' => Common::configValue('register_close_message', 'customer')];

        $phoneArea  = Common::getPhoneArea();
        $form = new UserRegisterForm($phoneArea, $this->entityManager);

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if($form->isValid()) {
                $data = $form->getData();
                $userInfo = $this->shopUserManager->userRegister($data);
                if(!$userInfo) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('注册错误!'));
                    return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', ['action' => 'userRegister'], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user', ['action' => 'userRegister']);
                }

                $this->shopPlugin()->unsetPhoneCaptchaData();//如果有手机验证码，这里进行session注销
                $this->getEventManager()->trigger('shop.user.register.post', $this, ['user' => $userInfo]);

                if($userInfo->getUserStatus() == 3) return $this->redirect()->toRoute('shop-user');

                return !empty($data['httpReferer']) ? $this->redirect()->toUrl(urldecode($data['httpReferer'])) : $this->redirect()->toRoute('shop');
            }
        }

        $httpReferer = $this->params()->fromQuery('httpReferer', '');
        if(!empty($httpReferer)) $form->get('httpReferer')->setValue($httpReferer);

        //第三方登录项
        $enableLogin = $this->shopPlugin()->enableOtherLogin();

        $userRegisterPartial = $this->shopPlugin()->shopPartial('userLogin');

        return ['form' => $form, 'phoneArea' => $phoneArea, 'enableLogin' => $enableLogin, 'userRegisterPartial' => $userRegisterPartial];
    }

    /**
     * 手机号码注册
     * @return array|\Laminas\Http\Response|mixed
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function phoneRegisterAction()
    {
        if (!Common::configValue('quick_register', 'customer')) return $this->response->setContent('Quick Register Close');

        $this->layout()->setVariable('titleName', $this->translator->translate('会员注册'));

        //判断会员注册是否关闭
        if(Common::configValue('register_status', 'customer') != 1) return ['registerStatus' => false, 'registerCloseMessage' => Common::configValue('register_close_message', 'customer')];

        $phoneArea  = Common::getPhoneArea();
        $form = new UserPhoneRegisterForm($phoneArea, $this->entityManager);

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $data['userName'] = $data['userPhone'];
            $form->setData($data);
            if($form->isValid()) {
                $data = $form->getData();
                $userInfo = $this->shopUserManager->userRegister($data);
                if(!$userInfo) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('注册错误!'));
                    return !empty($data['httpReferer']) ? $this->redirect()->toRoute('shop-user', ['action' => 'phoneRegister'], ['query' => ['httpReferer' => urldecode($data['httpReferer'])]]) : $this->redirect()->toRoute('shop-user', ['action' => 'phoneRegister']);
                }

                $this->shopPlugin()->unsetPhoneCaptchaData();//如果有手机验证码，这里进行session注销
                $this->getEventManager()->trigger('shop.user.register.post', $this, ['user' => $userInfo]);

                if($userInfo->getUserStatus() == 3) return $this->redirect()->toRoute('shop-user');

                return !empty($data['httpReferer']) ? $this->redirect()->toUrl(urldecode($data['httpReferer'])) : $this->redirect()->toRoute('shop');
            }
        }

        $httpReferer = $this->params()->fromQuery('httpReferer', '');
        if(!empty($httpReferer)) $form->get('httpReferer')->setValue($httpReferer);

        //第三方登录项
        $enableLogin = $this->shopPlugin()->enableOtherLogin();

        $userRegisterPartial = $this->shopPlugin()->shopPartial('userLogin');

        return ['form' => $form, 'phoneArea' => $phoneArea, 'enableLogin' => $enableLogin, 'userRegisterPartial' => $userRegisterPartial];
    }

    /**
     * 会员退出操作
     * @return \Laminas\Http\Response
     */
    public function userLogoutAction()
    {
        $this->shopUserManager->userLogout();

        return $this->redirect()->toRoute('shop');
    }

    /**
     * 邮件认证
     * @return \Laminas\Http\Response
     */
    public function userEmailAuditAction()
    {
        $auditCode = $this->params()->fromQuery('auditCode', '');
        if(empty($auditCode)) return $this->redirect()->toRoute('shop');

        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userEmailAuditCode' => $auditCode]);
        if($userInfo == null || $userInfo->getUserStatus() != 3) return $this->redirect()->toRoute('shop');

        $this->shopUserManager->updateUserStatus(1, $userInfo->getUserId());
        $this->shopUserManager->updateUserEmailAuditCode('', $userInfo->getUserId());

        $this->flashMessenger()->addSuccessMessage($this->translator->translate('认证完成，您可以进行登录操作了。'));
        return $this->redirect()->toRoute('shop-user');
    }

    /**
     * 邮件找回密码
     * @return \Laminas\Http\Response|ForgetPasswordForm[]
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     * @throws \PHPMailer\PHPMailer\Exception
     */
    public function userForgetPasswordAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('邮件密码找回'));

        $forgetPasswordUrl = Common::configValue('forget_password_url', 'customer');
        if (!empty($forgetPasswordUrl)) return $this->redirect()->toUrl($forgetPasswordUrl);

        $emailServiceState = Common::configValue('email', 'config')['email_service_state'];

        $form = new ForgetPasswordForm();

        if($this->getRequest()->isPost() && $emailServiceState == 1) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userName' => $data['userName'], 'userEmail' => $data['userEmail']]);
                if($userInfo == null) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('该客户的信息不存!'));
                    return $this->redirect()->toRoute('shop-user', ['action' => 'userForgetPassword']);
                }

                $editCode   = Rand::getString(50);
                $editUrl    = $this->url()->fromRoute('shop-user', ['action' => 'userForgetPasswordEdit'], ['query' => ['editCode' => $editCode], 'force_canonical' => true]);

                $this->shopUserManager->updateUserForgotPasswordCode($editCode, $userInfo->getUserId());
                $sendStatus = ShopMessage::sendMail([
                    'mail'      => $userInfo->getUserEmail(),
                    'subject'   => $this->translator->translate('会员密码修改'),
                    'body'      => $userInfo->getUserName() . '<br>' . $this->translator->translate('您好，请点击下面的链接进行密码修改') . '<br><a href="'.$editUrl.'" target="_blank">' . $editUrl . '</a>'
                ]);

                if(!$sendStatus) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('发送错误，邮件服务未开启!'));
                } else {
                    $this->flashMessenger()->addSuccessMessage(sprintf($this->translator->translate('已经成功向您的邮箱 %s 发送了一封邮件，请根据邮件内容完成新密码设定'), $userInfo->getUserEmail()));
                }
                return $this->redirect()->toRoute('shop-user', ['action' => 'userForgetPassword']);
            }
        }

        return ['form' => $form, 'emailServiceState' => $emailServiceState];
    }

    /**
     * 密码重置
     * @return array|\Laminas\Http\Response
     */
    public function userForgetPasswordEditAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('密码重置'));

        if (Common::configValue('email', 'config')['email_service_state'] != 1) return $this->response->setContent($this->translator->translate('邮箱找回密码未启用'));

        $editCode = $this->params()->fromQuery('editCode');
        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userForgotPasswordCode' => $editCode]);
        if($userInfo == null) return $this->redirect()->toRoute('shop');

        $form = new ResetUserPasswordForm();

        if($this->getRequest()->isPost()) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $changeStatus = $this->shopUserManager->resetUserPassword($data['userPassword'], $userInfo->getUserId());
                if($changeStatus) {
                    $this->getEventManager()->trigger('shop.user.login-password-edit.post', $this, ['userInfo' => $userInfo, 'loginPassword' => $data['userPassword']]);

                    $this->flashMessenger()->addSuccessMessage($this->translator->translate('密码重置完成!'));
                    return $this->redirect()->toRoute('shop-user');
                } else {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('密码重置失败!'));
                    return $this->redirect()->toRoute('shop-user', ['action' => 'userForgetPasswordEdit'], ['query' => ['editCode' => $editCode]]);
                }
            }
        }

        return ['form' => $form, 'userInfo' => $userInfo];
    }

    /**
     * 手机找回密码
     * @return array|\Laminas\Http\Response
     */
    public function userPhoneForgetPasswordAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('手机密码找回'));

        $forgetPasswordUrl = Common::configValue('forget_password_url', 'customer');
        if (!empty($forgetPasswordUrl)) return $this->redirect()->toUrl($forgetPasswordUrl);

        //获取是否启用手机验证码
        $phoneMessage   = Common::readConfigFile('phoneMessage');
        $smsConfig      = Common::configValue('sms', 'config');
        $forgetPasswordSmsState = ($smsConfig['sms_state'] == 1 && !empty($phoneMessage[$smsConfig['sms_service_provider']]['captchaSmsTemplateId']));

        $step = 1;
        if ($this->shopPlugin()->getDbshopSessionData('forgetPasswordStep')) $step = $this->shopPlugin()->setDbshopSessionData('forgetPasswordStep', 1);
        if ($step < 1 || $step > 3) $step = 1;

        $phoneArea  = Common::getPhoneArea();
        $form = new PhoneForgetPasswordForm($step, $phoneArea);

        if($this->getRequest()->isPost() && $forgetPasswordSmsState) {
            $data = $this->params()->fromPost();
            $form->setData($data);
            if ($form->isValid()) {
                $data = $form->getData();
                $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userPhone' => $data['userPhone'], 'areaCode' => $data['areaCode']]);
                if ($userInfo == null) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('该手机号码不存在!'));
                    return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPassword']);
                }

                $this->shopPlugin()->setDbshopSessionData('forgetPasswordStep1', $data);
                $this->shopPlugin()->setDbshopSessionData('forgetPasswordStep', 2);
                return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPasswordNext']);
            }
        }

        return ['form' => $form, 'phoneArea' => $phoneArea, 'forgetPasswordSmsState' => $forgetPasswordSmsState];
    }

    /**
     * 手机找回密码下一步
     * @return array|\Laminas\Http\Response
     */
    public function userPhoneForgetPasswordNextAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('手机密码找回'));

        $step = $this->shopPlugin()->getDbshopSessionData('forgetPasswordStep');
        $data = $this->shopPlugin()->getDbshopSessionData('forgetPasswordStep1');
        if ($step != 2) return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPassword']);

        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userPhone' => $data['userPhone'], 'areaCode' => $data['areaCode']]);

        $form = new PhoneForgetPasswordForm($step);

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData(array_merge(['userPhone' => $data['userPhone']], $postData));
            if ($form->isValid()) {
                $postData = $form->getData();

                if ($data['userPhone'] != $this->shopPlugin()->getDbshopSessionData('phoneNumber')) {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('手机号码与申请的手机号码不相同!'));
                    return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPassword']);
                }

                $this->shopPlugin()->unsetPhoneCaptchaData();//这里进行手机验证码session注销
                $this->shopPlugin()->setDbshopSessionData('forgetPasswordStep', 3);
                return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPasswordEdit']);
            }
        }

        return ['form' => $form, 'userInfo' => $userInfo];
    }

    /**
     * 密码重置，手机找回密码
     * @return array|\Laminas\Http\Response
     */
    public function userPhoneForgetPasswordEditAction()
    {
        if($this->shopPlugin()->checkUserLoginStatus()) return $this->redirect()->toRoute('shop');

        $this->layout()->setVariable('titleName', $this->translator->translate('客户密码修改'));

        $step = $this->shopPlugin()->getDbshopSessionData('forgetPasswordStep');
        $data = $this->shopPlugin()->getDbshopSessionData('forgetPasswordStep1');
        if ($step != 3) return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPassword']);

        $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userPhone' => $data['userPhone'], 'areaCode' => $data['areaCode']]);

        $form = new PhoneForgetPasswordForm($step);

        if($this->getRequest()->isPost()) {
            $postData = $this->params()->fromPost();
            $form->setData($postData);
            if ($form->isValid()) {
                $postData = $form->getData();

                $changeStatus = $this->shopUserManager->resetUserPassword($postData['userPassword'], $userInfo->getUserId());
                if($changeStatus) {
                    $this->shopPlugin()->unsetDbshopSessionData('forgetPasswordStep1');
                    $this->shopPlugin()->unsetDbshopSessionData('forgetPasswordStep');

                    $this->getEventManager()->trigger('shop.user.login-password-edit.post', $this, ['userInfo' => $userInfo, 'loginPassword' => $data['userPassword']]);

                    $this->flashMessenger()->addSuccessMessage($this->translator->translate('密码重置完成!'));
                    return $this->redirect()->toRoute('shop-user');
                } else {
                    $this->flashMessenger()->addWarningMessage($this->translator->translate('密码重置失败!'));
                    return $this->redirect()->toRoute('shop-user', ['action' => 'userPhoneForgetPassword']);
                }
            }
        }

        return ['form' => $form, 'userInfo' => $userInfo];
    }

    /**
     * 注册协议
     * @return \Laminas\Http\PhpEnvironment\Response|\Laminas\Stdlib\ResponseInterface|mixed
     */
    public function registerAgreementAction()
    {
        return $this->getResponse()->setContent(Common::configValue('register_agreement', 'customer'));
    }

    /**
     * 第三方登录
     * @return \Laminas\Http\Response
     */
    public function otherLoginAction()
    {
        $loginType = $this->params()->fromQuery('loginType');

        $enableLogin = $this->shopPlugin()->enableOtherLogin();
        if (empty($enableLogin) || ($enableLogin && !in_array($loginType, $enableLogin))) return $this->redirect()->toRoute('shop-user');

        $loginService = new UserAppLogin($loginType, $this->url()->fromRoute('shop-user', ['action' => 'otherLoginCallBack', 'id' => $loginType], ['force_canonical' => true]));
        $loginService->toLogin();
    }

    /**
     * 回调或者绑定处理
     * @return \Laminas\Http\Response
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function otherLoginCallBackAction()
    {
        $loginType  = $this->params()->fromRoute('id', '');
        $enableLogin = $this->shopPlugin()->enableOtherLogin();
        if (empty($enableLogin) || !in_array($loginType, $enableLogin)) return $this->redirect()->toRoute('shop-user');

        $loginService   = new UserAppLogin($loginType, $this->url()->fromRoute('shop-user', ['action' => 'otherLoginCallBack', 'id' => $loginType], ['force_canonical' => true]));
        $loginService->loginCallBack();
        $openId         = $loginService->getOpenId();
        $unionId        = $loginService->getUnionId();

        //如果已经登录，那么这时为将注册账号与第三方绑定登录
        if ($this->shopPlugin()->checkUserLoginStatus()) {
            $userOtherLogin = $this->entityManager->getRepository(UserOtherLogin::class)->shopFindUserOtherLogin($openId, $unionId, $loginType);
            if ($userOtherLogin) {
                if (!empty($unionId) && $unionId != $userOtherLogin->getUnionId()) $this->userOtherLoginManager->editUserOtherLogin(['unionId' => $unionId], $userOtherLogin);
                $this->flashMessenger()->addWarningMessage($this->translator->translate('您的账户已经在系统中绑定，不能重复绑定!'));
            } else {
                $userId = $this->shopPlugin()->getUserLoginData('user_id');
                $otherLoginData = [
                    'userId'    => $userId,
                    'openId'    => $openId,
                    'olAddTime' => time(),
                    'loginType' => $loginType
                ];
                if (!empty($unionId)) $otherLoginData['unionId'] = $unionId;
                $this->userOtherLoginManager->addUserOtherLogin($otherLoginData);
                $loginService->clearOtherLoginSession();

                $this->flashMessenger()->addSuccessMessage($this->translator->translate('账户绑定成功!'));
            }
            return $this->redirect()->toRoute('home-user', ['action' => 'accountBind']);
        }

        $userExists = false;    //判断会员是否存在
        //回调，看第三方登录表是否存在该登录信息
        $userOtherLogin = $this->entityManager->getRepository(UserOtherLogin::class)->shopFindUserOtherLogin($openId, $unionId, $loginType);
        if ($userOtherLogin) {
            if (!empty($unionId) && $unionId != $userOtherLogin->getUnionId()) $this->userOtherLoginManager->editUserOtherLogin(['unionId' => $unionId], $userOtherLogin);
            $userExists = true;
        } else {
            $wechatLoginTypeArray = Common::wechatLoginTypeArray();
            if (isset($unionId) && !empty($unionId) && in_array($loginType, $wechatLoginTypeArray)) {
                $userOtherLogin = $this->entityManager->getRepository(UserOtherLogin::class)->shopFindUserOtherLoginUnionId($unionId, array_diff($wechatLoginTypeArray, [$loginType]));
                if ($userOtherLogin) {
                    $this->userOtherLoginManager->addUserOtherLogin(
                        [
                            'userId'    => $userOtherLogin->getUserId(),
                            'openId'    => $openId,
                            'unionId'   => $unionId,
                            'olAddTime' => time(),
                            'loginType' => $loginType
                        ]
                    );
                    $userExists = true;
                }
            }
        }

        if ($userExists) {//账户存在，进行登录处理
            $userInfo = $this->entityManager->getRepository(User::class)->findOneBy(['userId' => $userOtherLogin->getUserId()]);
            if ($userInfo->getUserStatus() == 2) {
                $this->flashMessenger()->addWarningMessage($this->translator->translate('您的账户处于关闭状态!'));
                return $this->redirect()->toRoute('shop-user');
            }
            if ($userInfo->getUserStatus() == 3) {
                $this->flashMessenger()->addWarningMessage($this->translator->translate('您的账户处于待审核状态!'));
                return $this->redirect()->toRoute('shop-user');
            }
            $this->shopUserManager->userLoginSession($userInfo);
            $loginService->clearOtherLoginSession();

            $this->getEventManager()->trigger('shop.user.login.post', $this, ['user' => $userInfo]);

            return $this->redirect()->toRoute('shop-user');
        }

        return $this->redirect()->toRoute('shop-user', ['action' => 'otherUserRegister', 'id' => $loginType]);
    }

    /**
     * @return array|\Laminas\Http\Response|ViewModel
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function otherUserRegisterAction()
    {
        $t = $this->params()->fromQuery('t', '');
        $registerType = empty($t) ? '' : 'bind';

        //判断会员注册是否关闭
        if(empty($registerType) && Common::configValue('register_status', 'customer') != 1) return ['registerStatus' => false, 'registerCloseMessage' => Common::configValue('register_close_message', 'customer')];

        $loginType  = $this->params()->fromRoute('id', '');
        $enableLogin = $this->shopPlugin()->enableOtherLogin();
        if (empty($enableLogin) || ($enableLogin && !in_array($loginType, $enableLogin))) return $this->redirect()->toRoute('shop-user');

        $loginService   = new UserAppLogin($loginType, $this->url()->fromRoute('shop-user', ['action' => 'otherLoginCallBack', 'id' => $loginType], ['force_canonical' => true]));
        $openId         = $loginService->getOpenId();
        $unionId        = $loginService->getUnionId();

        if ($registerType == 'bind') {//绑定现有账户
            $view = new ViewModel();
            $view->setTemplate('shop/user/other-user-login');

            $form = new OtherUserLoginForm($this->entityManager);
            if($this->getRequest()->isPost()) {
                $postData = $this->params()->fromPost();
                $form->setData($postData);
                if ($form->isValid()) {
                    $data = $form->getData();
                    $loginStatus = $this->shopUserManager->userLogin($data);
                    if(is_numeric($loginStatus) && $loginStatus == -1) {
                        $this->flashMessenger()->addWarningMessage($this->translator->translate('登录信息错误!'));
                        return $this->redirect()->toRoute('shop-user', ['action' => 'otherUserRegister', 'id' => $loginType], ['query' => ['t' => 'bind']]);
                    }

                    $otherLoginData = [
                        'userId'    => $loginStatus->getUserId(),
                        'openId'    => $openId,
                        'olAddTime' => time(),
                        'loginType' => $loginType
                    ];
                    if (!empty($unionId)) $otherLoginData['unionId'] = $unionId;
                    $this->userOtherLoginManager->addUserOtherLogin($otherLoginData);
                    $loginService->clearOtherLoginSession();

                    $this->getEventManager()->trigger('shop.user.login.post', $this, ['user' => $loginStatus]);

                    return $this->redirect()->toRoute('shop');
                }
            }

            return $view->setVariables(['form' => $form, 'loginType' => $loginType]);
        } else {//建立新账户
            $otherUserInfo = $loginService->getLoginUserInfo();

            $phoneArea  = Common::getPhoneArea();
            $form       = new OtherUserRegisterForm($phoneArea, $this->entityManager);
            if($this->getRequest()->isPost()) {
                $postData = $this->params()->fromPost();
                $form->setData($postData);
                if ($form->isValid()) {
                    $data = $form->getData();
                    $userInfo = $this->shopUserManager->userRegister($data);
                    if(!$userInfo) {
                        $this->flashMessenger()->addWarningMessage($this->translator->translate('建立新账户错误!'));
                        return $this->redirect()->toRoute('shop-user', ['action' => 'otherUserRegister', 'id' => $loginType]);
                    }

                    $this->shopPlugin()->unsetPhoneCaptchaData();//如果有手机验证码，这里进行session注销

                    $otherLoginData = [
                        'userId'    => $userInfo->getUserId(),
                        'openId'    => $openId,
                        'olAddTime' => time(),
                        'loginType' => $loginType
                    ];
                    if (!empty($unionId)) $otherLoginData['unionId'] = $unionId;
                    $this->userOtherLoginManager->addUserOtherLogin($otherLoginData);
                    $loginService->clearOtherLoginSession();

                    $this->getEventManager()->trigger('shop.user.register.post', $this, ['user' => $userInfo]);

                    if($userInfo->getUserStatus() == 3) return $this->redirect()->toRoute('shop-user');

                    return $this->redirect()->toRoute('shop');
                }
            }

            $form->setData(['userName' => $otherUserInfo['nickname']]);

            return ['form' => $form, 'phoneArea' => $phoneArea, 'loginType' => $loginType];
        }
    }
}